/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2016，所有权利保留。
 * <p>
 * 项目名：	notify-core
 * 文件名：	HttpsClient.java
 * 模块说明：
 * 修改历史：
 * 2016-2-15 - zhangyanbo - 创建。
 */
package study.saas.common.util.http;

import org.apache.commons.lang.StringUtils;

import javax.net.ssl.*;
import java.io.OutputStream;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author zhangyanbo
 */
public class HttpsClient extends HttpClient {

    public String posts(String url, String body, Map<String, String> headers) throws Exception {
        return getResult(url, body, "POST", headers);
    }

    public String posts(String url, String body, Map<String, String> params,
                        Map<String, String> headers) throws Exception {
        String paramString = getUrlParamsByMap(params);
        if (StringUtils.isNotEmpty(paramString)) {
            url = url + "?" + paramString;
        }
        return getResult(url, body, "POST", headers);
    }

    public String gets(String url, Map<String, String> params, Map<String, String> headers)
            throws Exception {
        String paramString = getUrlParamsByMap(params);
        if (StringUtils.isNotEmpty(paramString)) {
            url = url + "?" + paramString;
        }
        return getResult(url, null, "GET", headers);
    }

    private String getResult(String url, String body, String method, Map<String, String> headers)
            throws Exception {
        HttpsURLConnection conn = null;
        OutputStream out = null;
        try {
            logger.info("[{}],HTTPS请求[{}],header[{}],body[{}]", url, method);
            SSLUtils.ignoreSsl();
            conn = getConnections(new URL(url), method, headers);
            if (body != null) {
                out = conn.getOutputStream();
                out.write(body.getBytes("UTF-8"));
                out.close();
            }
            String s = getResponseBodyAsString(conn);
            logger.info("[{}],HTTPS请求[{}],返回结果[{}]", url, method);
            if (conn.getResponseCode() >= 400) {
                logger.error("调用服务出错:{}", s);
                throw new Exception(conn.getResponseMessage());
            }
            return s;
        } finally {
            if (out != null) {
                out.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    private HttpsURLConnection getConnections(URL url, String method, Map<String, String> headers)
            throws Exception {
        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[]{
                new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);

        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setDoInput(true);
        if ("POST".equals(method)) {
            conn.setDoOutput(true);
        }
        conn.setConnectTimeout(connectTimeout);
        conn.setReadTimeout(readTimeout);
        if (headers != null) {
            for (Entry<String, String> header : headers.entrySet()) {
                conn.setRequestProperty(header.getKey(), header.getValue());
            }
        }
        conn.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

        return conn;
    }

    private static class DefaultTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

    }

}
